<template>
  <div class="container">
    <div class="app-container">
      <div>
        <el-button
          type="primary"
          size="mini"
          @click="visible = true"
        >添加角色</el-button>
      </div>

      <!-- 表格 -->
      <el-table
        v-loading="loading"
        :data="roleList"
        style="width: 100%; margin-top: 30px"
        border
        :header-cell-style="{ background: '#f5f6f8' }"
      >
        <el-table-column label="序号" width="80">
          <template #default="{ $index }">
            <!-- 第一页索引和其他页数索引要叠加,
            用当前索引+1去加前面的索引，前面索引运算用当前页数-1（第一页不用叠加），*一页显示几条 -->
            {{ $index + pagesize * (page - 1) + 1 }}
          </template>
        </el-table-column>

        <el-table-column label="角色" width="300">
          <template #default="{ row }">
            <el-input
              v-if="row.isEdit"
              v-model="row.editRow.name"
              size="mini"
              style="width: 250px"
            />
            <span v-else>{{ row.name }}</span>
          </template>
        </el-table-column>

        <el-table-column label="启用" width="200">
          <template #default="{ row }">
            <el-switch
              v-if="row.isEdit"
              v-model="row.editRow.state"
              :active-value="1"
              :inactive-value="0"
            />
            <span v-else>{{ row.state ? "已启用" : "禁用" }}</span>
          </template>
        </el-table-column>

        <el-table-column label="描述" width="600">
          <template #default="{ row }">
            <el-input
              v-if="row.isEdit"
              v-model="row.editRow.description"
              type="textarea"
            />
            <span v-else> {{ row.description }}</span>
          </template>
        </el-table-column>

        <el-table-column label="操作">
          <template #default="{ row }">
            <span v-if="row.isEdit">
              <el-button
                size="mini"
                type="primary"
                @click="onUpdate(row)"
              >确定</el-button>
              <el-button size="mini" @click="onCancel(row)">取消</el-button>
            </span>
            <span v-else>
              <el-button
                type="text"
                @click="onAllotPerm(row.id)"
              >分配权限</el-button>
              <el-button type="text" @click="row.isEdit = true">编辑</el-button>
              <el-popconfirm
                title="确认删除角色吗？"
                @onConfirm="onDel(row.id)"
              >
                <el-button slot="reference" type="text">删除</el-button>
              </el-popconfirm>
            </span>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <el-row type="flex" justify="center">
        <el-pagination
          layout="prev, pager, next"
          :total="total"
          :page-size="pagesize"
          :current-page="page"
          @current-change="handleCurrentChange"
        />
      </el-row>

      <!-- 新增角色弹出层 -->
      <el-dialog
        :visible.sync="visible"
        width="500PX"
        title="新增角色"
        :close-on-click-modal="false"
      >
        <el-form
          ref="formRef"
          label-width="100px"
          style="width: 400px"
          :model="formData"
          :rules="rules"
        >
          <el-form-item label="角色名称" prop="name">
            <el-input v-model="formData.name" size="mini" />
          </el-form-item>
          <el-form-item label="启用">
            <el-switch
              v-model="formData.state"
              :active-value="1"
              :inactive-value="0"
            />
          </el-form-item>
          <el-form-item label="角色描述" prop="description">
            <el-input v-model="formData.description" type="textarea" />
          </el-form-item>
          <el-form-item>
            <el-form-item>
              <el-row type="flex" justify="center">
                <el-button type="primary" @click="onSubmit">确认</el-button>
                <el-button @click="visible = false">取消</el-button>
              </el-row>
            </el-form-item>
          </el-form-item>
        </el-form>
      </el-dialog>

      <!-- 分配权限弹出层 -->
      <el-dialog title="分配权限" :visible.sync="permVisible">
        <el-tree
          ref="treeRef"
          check-strictly
          :data="treeList"
          :props="{ label: 'name',value:'id'}"
          default-expand-all
          :expand-on-click-node="false"
          node-key="id"
          show-checkbox
          :default-checked-keys="permIds"
        />
        <template #footer>
          <el-row>
            <el-button size="small" type="primary" @click="onAssignPerm">确定</el-button>
            <el-button
              size="small"
              @click="permVisible = false"
            >取消</el-button>
          </el-row>
        </template>
      </el-dialog>
    </div>
  </div>
</template>

<!-- 1.渲染列表
  1.封装api
  2.在method封装调用api方法
  3.在created中调用一次调用api方法
  4.在data定义接受数据变量
  5.渲染数据-
 -->

<!-- 2.表格有分页，索引处理
  1.利用插槽获取当前索引号
  2.索引算法  当前索引+1+（（当前页数-1）*显示行数）
  3.蒙层定义布尔值，开始为false
  4.当发请求表格开启v-loading蒙层
  5.当数据回来蒙层一处
  -->

<!-- 4.点击编辑出现行内编辑，多个编辑也可以出现多个编辑框
    1.对回来的数据进行遍历，给每个对象添加一个变量isEit，值为布尔值
    2.给表格每格数据都进行互斥显示，当布尔值为true时显示编辑框，当false时显示文本
    3.因为vue2的响应式原理是在创建但是对打他的数据的数据进行劫持添加get和set方法，所以在创建后添加的属性都不是响应式的，要设置为响应式数据
    4.this.$set(item,isEdit,false)

    -->

<!-- 5.行内编辑点击取消还原数据
      1.获取到数据时备份一份数据渲染输入框
      2.因为后面添加vue2后面添加不支持响应式。所以用$set
      3.当用户点击取消时，将备份数据还原为初始数据
     -->

<!-- 6.编辑更新数据
      1.封装api
      2.将备份数据和id发送到后台
      3.更新成功后提示用户
      4.关闭输入框在覆盖row时赋值
      5.更新row的数据，用Object.assign(row,{isEdit：false，...row.editRow})
     -->

<!-- 7.删除角色
    1.封装api
    2.成功提示用户
    3.当前数据是当前页数的list的最后一条时，page页数-1
    4.调用刷新界面方法
    -->

<!--8.给角色分配权限
      1.创建弹出层组件进行显示与隐藏
      2.当用户点击分配时获取权限列表、获取id进行数据回填，将id挂载到全局this.id = id
      3.渲染组织列表转换为树形结构,添加选中按钮里面有一个方法选中按钮时触发，当选中子节点时不默认选中父节点check-strictly，用$refs.treeRef.getCheckedKeys())获取选中的id·1
      4.当点击确定时获取取树的ref调用他身上的选中方法
     -->
<script>
import { getPerMsAPI } from '@/api/permission'
import {
  addRoleAPI,
  assignPermAPI,
  delRoleAPI,
  editRoleAPI,
  getRoleListAPI,
  permDetailAPI
} from '@/api/role'
import { convertToTree } from '@/utils'
export default {
  name: 'Role',
  data() {
    return {
      permIds: [],
      id: '',
      treeList: [], // 添加权限的组织列表
      permVisible: false, // 分配权限弹出层显示与隐藏
      loading: false, // 遮罩蒙层
      page: 1,
      total: 0,
      pagesize: 5,
      roleList: [],
      visible: false,
      formData: {
        name: '',
        description: '',
        state: 0
      }, // 定义弹出层对象
      rules: {
        name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
        description: [
          { required: true, message: '请输入角色描述', trigger: 'blur' }
        ]
      }
    }
  },
  watch: {
    visible(newValue) {
      if (!newValue) {
        this.$refs.formRef.resetFields()
        this.formData = {
          name: '',
          description: '',
          state: 0
        }
      }
    }
  },
  created() {
    this.onload()
  },
  methods: {
    async onload() {
      this.loading = true
      // 初始数据
      const { data } = await getRoleListAPI({
        page: this.page,
        pagesize: this.pagesize
      })
      // 手动添加数据isEdit
      data.rows.forEach((item) => {
        this.$set(item, 'isEdit', false) // 第一个值是当前对象，第二个值是要添加的属性，第三个是这个值得方法
        this.$set(item, 'editRow', {
          name: item.name,
          description: item.description,
          state: item.state
        })
      })
      this.roleList = data.rows
      this.total = data.total
      this.loading = false
    },
    // 角色分配权限
    async onAllotPerm(id) {
      this.id = id
      Promise.all([getPerMsAPI(), permDetailAPI(id)])
        .then((res) => {
          this.permVisible = true
          this.treeList = convertToTree(res[0].data)
          this.permIds = res[1].data.permIds
        })
        .catch((err) => {
          console.log('err  --->', err)
        })
    },
    // 提交权限
    async onAssignPerm() {
      // console.log('this.$refs.treeRef.getCheckedKeys()  --->', this.$refs.treeRef.getCheckedKeys())
      await assignPermAPI({
        id: this.id,
        permIds: this.$refs.treeRef.getCheckedKeys()
      })
      this.$message.success('添加成功')
      this.permVisible = false
    },
    // 行内编辑确认
    async onUpdate(row) {
      if (row.editRow.name && row.editRow.description) {
        await editRoleAPI({
          id: row.id,
          ...row.editRow
        })
        this.$message.success('更新角色成功')
        // 更新角色
        Object.assign(row, {
          isEdit: false,
          ...row.editRow
        })
      } else {
        this.$message.info('角色名称和角色描述不能为空')
      }
    },
    // 行内编辑取消
    onCancel(row) {
      row.isEdit = false
      row.editRow = {
        name: row.name,
        state: row.state,
        description: row.description
      }
    },
    // 修改页数
    handleCurrentChange(val) {
      this.page = val
      this.onload()
    },
    // 删除角色
    async onDel(id) {
      await delRoleAPI(id)
      this.$message.success('删除成功')
      if (this.roleList.length === 1) {
        this.page = this.page - 1
      }
      this.onload()
    },
    // 弹出层的确认事件
    async onSubmit() {
      await this.$refs.formRef.validate()
      const res = await addRoleAPI(this.formData)
      console.log('res  --->', res)
      this.visible = false
      this.$message.success('新增成功')
      this.onload()
    }
  }
}
</script>
<style lang="scss" scoped>
.app-container {
  padding: 10px;
  font-size: 14px;
}
</style>
